/**
 * Copyright(c) by JNet Smartware Group.
 * All rights reserved. Not distribution or redistribution without
 * any permission of JNet Smartware Group.
 * 
 * @author thuc
 * 2010/03/15
 */
package vn.smartware.co.server.dao.initialize;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import vn.smartware.co.framework.bean.LoginDTO;
import vn.smartware.co.framework.exception.ServerException;
import vn.smartware.co.framework.form.LoginForm;
import vn.smartware.co.java.net.commons.EncryptionUtils;
import vn.smartware.co.java.net.commons.Utils;
import vn.smartware.co.server.dao.factory.AbstractLoginDAO;
import vn.smartware.co.server.sql.factory.AbstractLoginSQLManager;
import vn.smartware.co.server.sql.factory.SQLFactory;

/**
 * @author thuctt
 *
 */
public class LoginDAO extends AbstractLoginDAO {

	private static Log log = LogFactory.getLog(LoginDAO.class);
	
	/**
	 * check login name exist
	 * 
	 * @param form
	 * @param conn
	 * @return boolean
	 * @throws ServerException
	 */
	public boolean chkUserNameExist(LoginForm form, Connection conn) throws ServerException {
		
		AbstractLoginSQLManager manager = SQLFactory.createLoginSQLManager();
		ResultSet rs = null;
		int count = 0;
		try {
			manager.makeChkUserNameExistSQL(form, conn);
			rs = manager.executeQuery();
			if (rs.next()){
				count = rs.getInt("CNT");
			}
			
			if (count > 0){
				log.info("Login name exist.");
				return true;
			}
			log.info("Login name not exist.");
			return false;
			
		} catch (SQLException e) {
			log.error("SQLException: ", e);
			throw new ServerException(e.getMessage());
		} finally {
			try {
				manager.close(rs);
				manager.close();
				
			} catch (SQLException e) {
				log.error("SQLException: ", e);
				throw new ServerException(e.getMessage());
			}
		}
	}
	
	/**
	 * check account exist
	 * 
	 * @param form
	 * @param conn
	 * @throws ServerException
	 */
	public void getLoginInfo(LoginForm form, Connection conn) throws ServerException {
		
		AbstractLoginSQLManager manager = SQLFactory.createLoginSQLManager();
		ResultSet rs = null;
		EncryptionUtils encryptor = EncryptionUtils.getInstance();
		try {
			manager.makeGetLoginInfoSQL(form, conn);
			rs = manager.executeQuery();
			if (rs.next()){
				form.setPassword(encryptor.decrypt(rs.getString("PASSWORD")));
				form.setUserCd(rs.getInt("USER_ID"));
			}
			
		} catch (SQLException e) {
			log.error("SQLException: ", e);
			throw new ServerException(e.getMessage());
		} finally {
			try {
				manager.close(rs);
				manager.close();
				
			} catch (SQLException e) {
				log.error("SQLException: ", e);
				throw new ServerException(e.getMessage());
			}
		}
	}
	
	/**
	 * chkUserLogin
	 * 
	 * @param form
	 * @param conn
	 * @return LoginForm
	 * @throws ServerException
	 */
	public LoginForm getUserInfo(LoginForm form, Connection conn) throws ServerException {
		
		AbstractLoginSQLManager manager = SQLFactory.createLoginSQLManager();
		ResultSet rs = null;
		int count = 0;
		try {
			manager.makeGetUserInfoSQL(form, conn);
			rs = manager.executeQuery();
			if (rs.next()){
				LoginDTO user = (LoginDTO)form.getUserDTO();
				
				user.setLoginNo(rs.getInt("NO"));
				user.setUserId(rs.getInt("USER_ID"));
				user.setName(Utils.toEmpty(rs.getString("FULL_NAME")));
				user.setLoginName(form.getUsername());
				user.setLoginPass(form.getPassword());
				user.setInitPrgId(Utils.toEmpty(rs.getString("INIT_PRG_ID")));
				
				form.setLoginTryNumber(rs.getInt("LOGIN_TRY_NUMBER"));
				form.setUserDTO(user);
				
				count++;
			}
			log.info(count + " rows selected.");
			return form;
			
		} catch (SQLException e) {
			log.error("SQLException: ", e);
			throw new ServerException(e.getMessage());
		} finally {
			try {
				manager.close(rs);
				manager.close();
				
			} catch (SQLException e) {
				log.error("SQLException: ", e);
				throw new ServerException(e.getMessage());
			}
		}
	}
	
	/**
	 * getMaxLoginNo
	 * 
	 * @param conn
	 * @return LoginForm
	 * @throws ServerException
	 */
	public int getMaxLoginNo(Connection conn) throws ServerException {
		
		AbstractLoginSQLManager manager = SQLFactory.createLoginSQLManager();
		ResultSet rs = null;
		int idx = 0;
		try {
			manager.makeGetMaxLoginNoSQL(conn);
			rs = manager.executeQuery();
			if (rs.next()){
				idx = rs.getInt("MAX_NO");
				
			}
			return idx;
			
		} catch (SQLException e) {
			log.error("SQLException: ", e);
			throw new ServerException(e.getMessage());
		} finally {
			try {
				manager.close(rs);
				manager.close();
				
			} catch (SQLException e) {
				log.error("SQLException: ", e);
				throw new ServerException(e.getMessage());
			}
		}
	}

	/**
	 * increase trying number if login error
	 * 
	 * @param form
	 * @param conn
	 * @throws ServerException
	 */
	public void increaseTryNumber(LoginForm form, Connection conn) throws ServerException {

		AbstractLoginSQLManager manager = SQLFactory.createLoginSQLManager();
		int count = 0;
		try {
			manager.makeIncreaseTryNumberSQL(form, conn);
			count = manager.executeUpdate();
			
			log.info(count + " rows updated.");
			
		} catch (SQLException e) {
			log.error("SQLException: ", e);
			throw new ServerException(e.getMessage());
			
		} finally {
			try {
				manager.close();
				
			} catch (SQLException e) {
				log.error("SQLException: ", e);
				throw new ServerException(e.getMessage());
			}
		}
	}

	/**
	 * reset trying number to 0
	 * @param form
	 * @param conn
	 * @throws ServerException
	 */
	public void updateLoginSucessfulStatus(LoginForm form, Connection conn) throws ServerException {

		AbstractLoginSQLManager manager = SQLFactory.createLoginSQLManager();
		int count = 0;
		try {
			manager.makeUpdateLoginSucessfulStatusSQL(form, conn);
			count = manager.executeUpdate();
			
			log.info(count + " rows updated.");
			
		} catch (SQLException e) {
			log.error("SQLException: ", e);
			throw new ServerException(e.getMessage());
			
		} finally {
			try {
				manager.close();
				
			} catch (SQLException e) {
				log.error("SQLException: ", e);
				throw new ServerException(e.getMessage());
			}
		}
	}

	/**
	 * count login number
	 * 
	 * @param form
	 * @param conn
	 * @return int
	 * @throws ServerException
	 */
	public int countLoginTryNumber(LoginForm form, Connection conn) throws ServerException {
		
		AbstractLoginSQLManager manager = SQLFactory.createLoginSQLManager();
		ResultSet rs = null;
		int count = -1;
		try {
			manager.makeCountLoginTryNumberSQL(form, conn);
			rs = manager.executeQuery();
			if (rs.next()){
				count = rs.getInt("CNT");
			}
			
			return count;
			
		} catch (SQLException e) {
			log.error("SQLException: ", e);
			throw new ServerException(e.getCause().getMessage());
		} finally {
			try {
				manager.close(rs);
				manager.close();
				
			} catch (SQLException e) {
				log.error("SQLException: ", e);
				throw new ServerException(e.getCause().getMessage());
			}
		}
	}

	/**
	 * create first login time
	 * 
	 * @param form
	 * @param conn
	 * @throws ServerException
	 */
	public void createFirstLoginTime(LoginForm form, Connection conn) throws ServerException {

		AbstractLoginSQLManager manager = SQLFactory.createLoginSQLManager();
		int count = 0;
		try {
			manager.makecreateFirstLoginTimeSQL(form, conn);
			count = manager.executeUpdate();
			
			log.info(count + " rows updated.");
			
		} catch (SQLException e) {
			log.error("SQLException: ", e);
			throw new ServerException(e.getMessage());
			
		} finally {
			try {
				manager.close();
				
			} catch (SQLException e) {
				log.error("SQLException: ", e);
				throw new ServerException(e.getMessage());
			}
		}
	}

	/**
	 * lock account
	 * @param form
	 * @param conn
	 * @throws ServerException
	 */
	public void lockAccount(LoginForm form, Connection conn) throws ServerException {
		
		AbstractLoginSQLManager manager = SQLFactory.createLoginSQLManager();
		int count = 0;
		try {
			manager.makeLockAccountSQL(form, conn);
			count = manager.executeUpdate();
			
			log.info(count + " rows updated.");
			
		} catch (SQLException e) {
			log.error("SQLException: ", e);
			throw new ServerException(e.getMessage());
			
		} finally {
			try {
				manager.close();
				
			} catch (SQLException e) {
				log.error("SQLException: ", e);
				throw new ServerException(e.getMessage());
			}
		}
	}

	/**
	 * check account locked
	 * @param form
	 * @param conn
	 * @return String
	 * @throws ServerException
	 */
	public String isAccountLocked(LoginForm form, Connection conn) throws ServerException {
		
		AbstractLoginSQLManager manager = SQLFactory.createLoginSQLManager();
		ResultSet rs = null;
		String lockYmd = null;
		try {
			manager.makeIsAccountLockedSQL(form, conn);
			rs = manager.executeQuery();
			if (rs.next()){
				lockYmd = rs.getString("LOCK_OUT_DATE");
			}
			
		} catch (SQLException e) {
			log.error("SQLException: ", e);
			throw new ServerException(e.getMessage());
		} finally {
			try {
				manager.close(rs);
				manager.close();
				
			} catch (SQLException e) {
				log.error("SQLException: ", e);
				throw new ServerException(e.getMessage());
			}
		}
		return lockYmd;
	}

	/**
	 * reset login status
	 * @param form
	 * @param conn
	 * @throws ServerException
	 */
	public void resetLoginStatus(LoginForm form, Connection conn) throws ServerException {

		AbstractLoginSQLManager manager = SQLFactory.createLoginSQLManager();
		int count = 0;
		try {
			manager.makeResetLoginStatusSQL(form, conn);
			count = manager.executeUpdate();
			
			log.info(count + " rows updated.");
			
		} catch (SQLException e) {
			log.error("LoginDAO resetLoginStatus SQLException: ", e);
			throw new ServerException(e.getMessage());
			
		} finally {
			try {
				manager.close();
				
			} catch (SQLException e) {
				log.error("LoginDAO resetLoginStatus SQLException: ", e);
				throw new ServerException(e.getMessage());
			}
		}
	}

	/**
	 * update logout timer
	 * @param user
	 * @param conn
	 * @throws ServerException
	 */
	public void setLogoutTimer(LoginDTO user, Connection conn) throws ServerException {

		AbstractLoginSQLManager manager = SQLFactory.createLoginSQLManager();
		int count = 0;
		try {
			manager.makeSetLogoutTimerSQL(user, conn);
			count = manager.executeUpdate();
			
			log.info(count + " rows updated.");
			
		} catch (SQLException e) {
			log.error("SQLException: ", e);
			throw new ServerException(e.getMessage());
			
		} finally {
			try {
				manager.close();
				
			} catch (SQLException e) {
				log.error("SQLException: ", e);
				throw new ServerException(e.getMessage());
			}
		}
	}
}
